十进制转换二进制其实不是个复杂的问题,我们首先搞清楚原理:
整数部分:如果不是0,不断除2,直到除到1为止,得到的余数最后逆向排列输出;如果是0,直接输出
小数部分:小数部分m非0,则不断乘2,如果2*m超过1,则输出1,m=2*m-1;如果2*m不超过1,m=2*m
由于很多小数是无法完全转换为二进制的(比如0.7),为了避免死循环,我们需要得到一个精度(保留多少位小数)
以下是代码
#include <iostream>
using namespace std;
void convert_binary_integer(int n)
{
if(n==1)cout<<1;
else if(n==0)cout<<0;
else
{
convert_binary_integer(n/2);
cout<<(n%2);
}
}
void convert_binary_decimal(double m,int i)
{
if(i==1)
{
if(2*m>=1)
cout<<1;
else
cout<<0;
}
else
{
if(2*m>=1)
{
cout<<1;
convert_binary_decimal(2*m-1,i-1);
}
else
{
cout<<0;
convert_binary_decimal(2*m,i-1);
}
}
}
int main()
{
double num;int bit;
cout<<"请输入要转换的十进制数:";cin>>num;
int n=num;double m=num-n;
if(m!=0)
{
cout<<"请输入要保留的小数位数:";
cin>>bit;
}
cout<<"转换后为:";
convert_binary_integer(num);
if(m!=0)
{
cout<<'.';
convert_binary_decimal(m,bit);
}
return 0;
}
代码是很容易理解的。由我上面的说明大家很容易想到,有两种方法,一种是我写的递归,另一种是栈(有兴趣的读者可以自己尝试一下)。
程序是很容易,但是背后蕴含了一些问题,比如0.7显然是无法完全表示为二进制小数的,但输入0.7和100之后显示的后面n位都是0,这是怎么回事呢?
我们知道计算机内部的小数都是通过浮点数形式来表示,所以浮点数不是一个精确的值,好比我输入一个0.5,它未必就是0.5,有可能它是以0.49999999999998进行存储的,只不过显示出来是0.5而已,所以一次乘法不成问题,但是进行了50次,100次之后,当初那个0.5和0.49999999999998被放大很多了,所以会导致一些计算上的问题。这是系统误差,我本人不知道如何避免。但如果想要真正高精度的话,读者们不妨自己写一个小数类(这个小数类只要能存储、输出,还能执行*2或*2-1就可以了。
本文无任何版权,如需转载,不需注明,热烈欢迎各路大神来喷